import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart';
import 'package:nested/nested.dart';
import 'base_provider.dart';
import 'util/flutter_screenutil.dart';
@optionalTypeArgs
mixin BaseWidget<T extends StatefulWidget, V extends CunwControllNotify>
    on State<T> implements Lifecycle<V>, PageStateWidget {
  V mController;

  @override
  void initState() {
    super.initState();
    try {
      mController= context.read<V>();
      SchedulerBinding.instance.scheduleTask(initData, Priority.animation);
    } catch (e) {}
  }

  @override
  get createController => (context) {
        try {
          return context.watch<V>();
        } catch (e) {}
        return null;
      };

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    mController = createController(context);
  }

  initScreenUtil() {
    if (ScreenUtil.screenWidthDp==0x0) {
      ScreenUtil.instance = ScreenUtil(width: 375, allowFontScaling: false)
        ..init(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    initScreenUtil();
    return Material(
      child: CupertinoPageScaffold(
        backgroundColor: backgroundColor,
        resizeToAvoidBottomInset: resizeToAvoidBottomInset,
        navigationBar: title(context),
        child: _contentView(),
      ),
      color: Colors.transparent,
    );
  }

  Widget _contentView() {
    switch (mController?.state) {
      case PageState.loading:
        return loading();
      case PageState.complete:
        return initView(context);
      case PageState.fail:
        return error();
      case PageState.retry:
        return retry();
      default:
        return initView(context);
    }
  }

  @override
  Future onRetry(BuildContext context) {
    return initData();
  }

  Color get backgroundColor => Colors.white;

  bool get resizeToAvoidBottomInset => false;
}

mixin CreateProvider<V extends CunwControllNotify> {
  List<SingleChildWidget> createMultiValues() =>
      [cnprovider(createSingleValue)];

  V createSingleValue(BuildContext context);
}

/*
* 页面基础生命周期
* */
abstract class Lifecycle<V extends CunwControllNotify> {
  //初始化控制器
  Create<V> get createController;

  //初始化数据
  Future<dynamic> initData();

  //导航栏
  Widget title(BuildContext context);

  //内容
  Widget initView(BuildContext context);
}

/*
* 页面状态
* */

abstract class PageStateWidget {
  //加载状态
  Widget loading();

  //错误状态
  Widget error();

  //重试状态
  Widget retry();

  //加载完成状态
  Future onRetry(BuildContext context);
}

//基础页面
class BasePage extends StatelessWidget {
  final Widget child;
  final List<SingleChildWidget> data;

  const BasePage({Key key, this.data, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (data?.isNotEmpty == true) {
      return MultiProvider(
        providers: data,
        child: child,
      );
    }

    if (child is CreateProvider) {
      var list = (child as CreateProvider).createMultiValues();
      if (list.isNotEmpty) {
        return MultiProvider(
          providers: list,
          child: child,
        );
      }
    }

    return child;
  }
}


mixin CunwStlessWidget<V extends CunwControllNotify> on StatelessWidget
    implements CreateProvider<V>, Lifecycle<V>, PageStateWidget {
  initScreenUtil(context) {
    if (ScreenUtil.screenWidthDp==0x0) {
      ScreenUtil.instance = ScreenUtil(width: 375, allowFontScaling: false)
        ..init(context);
    }
  }

  @override
  Future initData() {
    // TODO: implement initData
    return null;
  }

  @override
  Widget build(BuildContext context) {
    initScreenUtil(context);
    return Material(
      child: CupertinoPageScaffold(
        backgroundColor: backgroundColor,
        resizeToAvoidBottomInset: false,
        navigationBar: title(context),
        child: _contentView(context),
      ),
      color: Colors.transparent,
    );
  }

  Widget _contentView(BuildContext context) {
    return Consumer<V>(
      builder: (BuildContext context, V value, Widget child) {
        switch (value?.state) {
          case PageState.loading:
            return loading();
          case PageState.complete:
            return child;
          case PageState.fail:
            return error();
          case PageState.retry:
            return retry();
          default:
            return child;
        }
      },
      child: initView(context),
    );
  }

  @override
  List<SingleChildWidget> createMultiValues() =>
      [cnprovider(createSingleValue)];

  @override
  get createController => (context) {
        try {
          return Provider.of<V>(context);
        } catch (e) {}
        return null;
      };

  Color get backgroundColor => Colors.white;
}
